package edu.cornell.lsi;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import edu.cornell.cs.lsi.projone.common.util.AppUtil;
import edu.cornell.cs.lsi.projone.model.SessionTableData;
import edu.cornell.cs.lsi.projone.service.SessionTableManager;

// Servlet for Refresh action
public class RefreshServlet extends HttpServlet {

	ServletConfig config;
	private long sessionTimeout = 0;
	private SessionTableManager sessionTableMgr;

	// Read the context parameters
	@Override
	public void init(ServletConfig config) throws ServletException {

		this.config = config;
		super.init(config);
		ServletContext context = getServletContext();
		sessionTimeout = Long.valueOf(context
				.getInitParameter("session_timeout_msec"));
		sessionTableMgr = new SessionTableManager();
	}

	// Calls doPost for processing
	@Override
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	// POST method process request and send response
	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		Cookie cookie = null;
		String sessionID = null;
		double cookieVersionID = 0;
		double versionID = 0;
		int counter = 1;
		String value = null;
		String timeStamp = null;

		// Get the current time
		DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Date date = new Date();
		String currentTime = dateFormat.format(date);
		Cookie[] cookies = request.getCookies();

		// If cookie is null redirect to home page
		if (cookies == null) {
			// response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
			// response.setHeader("Location", "http://localhost:8080/lsi/home");
			// response.setContentType("text/html");
			RequestDispatcher dispatch = request.getRequestDispatcher("/home");
			dispatch.forward(request, response);
			return;

			// Retrieve the cookie values if not null
		} else {
			cookie = cookies[0];
			String[] cookieValues = cookie.getValue().split(" ");
			sessionID = cookieValues[0];
			cookieVersionID = Double.parseDouble(cookieValues[1]);
			SessionTableData sessionData = null;

			// Check if Session Data Table has the session ID
			if (sessionTableMgr.containsSession(sessionID)) {

				// Retrieve session data from table
				sessionData = sessionTableMgr.getEntry(sessionID,
						cookieVersionID);
				versionID = sessionData.getVersionNumber();
				value = sessionData.getSessionVal();
				counter = sessionData.getCounter() + 1;
				timeStamp = sessionData.getSessionCreationTime();

				// if session timed out redirect to logout page
				if (SessionTableManager.isTimedOut(timeStamp, currentTime,
						sessionTimeout)) {
					// response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
					// response.setHeader("Location",
					// "http://localhost:8080/lsi/logout");
					// response.setContentType("text/html");
					RequestDispatcher dispatch = request
							.getRequestDispatcher("/logout");
					dispatch.forward(request, response);
					return;
				}

				// if version mismatch redirect to error page
				if (cookieVersionID != versionID) {
					// response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
					// response.setHeader("Location","http://localhost:8080/lsi/error");
					// response.setContentType("text/html");

					RequestDispatcher dispatch = request
							.getRequestDispatcher("/error");
					dispatch.forward(request, response);
					return;
				}

				// increment the version
				versionID += 1;

				// Fetch session data from other AS's
			} else {

				sessionData = SessionTableManager.fetchSession(sessionID + " "
						+ cookieVersionID);

				if (sessionData == null) {
					// response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
					// response.setHeader("Location",
					// "http://localhost:8080/lsi/logout");
					// response.setContentType("text/html");
					RequestDispatcher dispatch = request
							.getRequestDispatcher("/logout");
					dispatch.forward(request, response);
					return;
				} else {
					versionID = sessionData.getVersionNumber();
					value = sessionData.getSessionVal();
					counter = sessionData.getCounter() + 1;
					timeStamp = sessionData.getSessionCreationTime();

					// if session timed out redirect to logout page
					if (SessionTableManager.isTimedOut(timeStamp, currentTime,
							sessionTimeout)) {
						// response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
						// response.setHeader("Location",
						// "http://localhost:8080/lsi/logout");
						// response.setContentType("text/html");
						RequestDispatcher dispatch = request
								.getRequestDispatcher("/logout");
						dispatch.forward(request, response);
						return;
					}

					// if version mismatch redirect to error page
					if (cookieVersionID != versionID) {
						// response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
						// response.setHeader("Location","http://localhost:8080/lsi/error");
						// response.setContentType("text/html");

						RequestDispatcher dispatch = request
								.getRequestDispatcher("/error");
						dispatch.forward(request, response);
						return;
					}

					// increment the version
					versionID += 1;
				}
			}

			// Update cookie value and session data
			sessionData.update(versionID, currentTime, counter, value);
			sessionTableMgr.addEntry(sessionData);
			String serverList = SessionTableManager.updateSession(sessionData);
			cookie.setValue(sessionID + " " + Double.toString(versionID) + " "
					+ serverList);

			// userSession.update(Integer.toString(versionID),
			// currentTime,counter,value);
		}

		response.addCookie(cookie);
		response.setContentType("text/html");

		PrintWriter out = response.getWriter();
		String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 "
				+ "Transitional//EN\">\n";
		out.println(docType
				+ "<HTML>\n"
				+ "<HEAD><TITLE>LSI Assignment 4</TITLE></HEAD>\n"
				+ "<body style=\"background-color:#E8E8E8;\">"
				+

				"<big><b>"
				+ "("
				+ counter
				+ ")"
				+ value
				+ "</big></b>"
				+ "<form method=POST action=\"replace\">"
				+ "<input type=submit name=cmd value=Replace>"
				+ "<input type=text name=NewText size=40 maxlength=1024>"
				+ " </form> "
				+ "<form method=POST action=\"refresh\"><input type=submit name=cmd value=Refresh></form>"
				+ "<form method=POST action=\"logout\">"
				+ "<input type=submit name=cmd value=LogOut>"
				+ "<br><br> IP Addr:Port - "
				+ InetAddress.getLocalHost().getHostAddress() + ":"
				+ AppUtil.getPort() + "</form></BODY></HTML>");

	}

}
